import java.util.Map;
import java.util.Iterator;
import java.util.HashMap;
import java.util.ArrayList;

class TablaSimbolos {

    TablaSimbolos tPadre = null;
    int num;
    HashMap<String, Simbolo> simbolos = new HashMap<String, Simbolo>();
    static HashMap<String, Simbolo> clases = new HashMap<String, Simbolo>();
    Simbolo sPadre=null;

    public TablaSimbolos(TablaSimbolos tablaPadre) {
    this.tPadre = tablaPadre;
    num = 0;
    if (tablaPadre != null) {
        num = tablaPadre.num + 1;
        }
    }
// Cuando utilizamos esto y porque no se incrementa num si no es el padre
    public TablaSimbolos(TablaSimbolos tablaPadre, Simbolo simboloPadre ) {
        this.tPadre = tablaPadre;
        num = 0;
        sPadre = simboloPadre;
    }

    public TablaSimbolos pop() {
        return tPadre;
    }

    public Simbolo obtenPadre(){
        return(sPadre);
    }
    
    public void nuevoSimbolo(String nombre, int tipoSimbolo, int tipo, int posicion) {
        Simbolo s = new Simbolo(nombre, tipoSimbolo, tipo, posicion);
        s.tPadre = this;
        simbolos.put(nombre, s);
    }

    public void nuevoSimbolo(String nombre, int tipoSimbolo, int tipo, int posicion, boolean esIndice) {
        Simbolo s = new Simbolo(nombre, tipoSimbolo, tipo, posicion, esIndice);
        s.tPadre = this;
        simbolos.put(nombre, s);
    }


    public void nuevoSimbolo(String nombre, int tipoSimbolo, int tipo, int posicion, int tam) {
        Simbolo s = new Simbolo(nombre, tipoSimbolo, tipo, posicion, tam);
        s.tPadre = this;
        simbolos.put(nombre, s);
    }

    public static void anyadirClase(Simbolo clase){
        clases.put(clase.getNombre(),clase);
    }

    public void meteMetodoAcabado(Simbolo s){
        s.tPadre = this;
        simbolos.put(s.getNombre()+s.getNumArgs(),s);
    }

    public Simbolo sacaMetodo(String nombre, int numArgumentos){
          return(simbolos.get(nombre+numArgumentos));
    }

    public boolean existeMetodo(String nombre, int num){
        return(!(simbolos.get(nombre+num)==null));
    }

    public static Simbolo obtenClase(String nomClase){
        return(clases.get(nomClase));
    }

    public static boolean existeClase(String nomClase){
        return(clases.containsKey(nomClase));
    }

    public Simbolo busca(String nombre) {
        Simbolo s = simbolos.get(nombre);
        if (s != null) {
            return s;
        }
        if (tPadre != null) {
            return tPadre.busca(nombre);
        }
        return null;
    }

    public boolean esDeMain(String nomSimbolo){
        boolean retorno=false;
        if(sPadre!=null){
            if(sPadre.esMain()){
                retorno=true;
            }
        }
        return retorno;
    }
    public boolean existeSimbolo(String nombre) {
        return simbolos.get(nombre) != null;
    }

    public boolean Emprat(String nombre) {
        return busca(nombre).emprat;
    }

    public int getNum() {
        return num;
    }
// util para recorrer la tabla hash
    public void pintaSimbolos() {

        Iterator i = simbolos.entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry me = (Map.Entry) i.next();
            System.out.println("La key: " + me.getKey() + "  " + me.getValue());
        }

    }
    
    public ArrayList obtenCampos(){
        
        ArrayList campos = new ArrayList();
        Simbolo sim;
        
        
              Iterator i = simbolos.entrySet().iterator();
            while (i.hasNext()) {
                Map.Entry me = (Map.Entry) i.next();
                sim = (Simbolo)me.getValue();
                if (sim.esCampo())
                {
                     campos.add(sim);                    
                 };
                
            }
            
            return campos;
        }
        
        
        
        
   };

